/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pgpproj.receiver;

import java.io.UnsupportedEncodingException;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.spec.SecretKeySpec;
import pgpproj.pgpframework.Message.PGPAuthMessage;
import pgpproj.pgpframework.Message.PGPConfMessage;
import pgpproj.pgpframework.Message.PGPMessage;
import pgpproj.pgpframework.authentication.VerifySignatureActor;
import pgpproj.pgpframework.authentication.algorithm.SignatureEnum;
import pgpproj.pgpframework.authentication.key.GeneratorKeyPair;
import pgpproj.pgpframework.crypto.algorithm.CipherAlgorithmEnum;
import pgpproj.pgpframework.crypto.engine.SymetricCipherEngine;
import pgpproj.pgpframework.hash.SHAHashGenerator;

/**
 *
 * @author ufabc
 */
public class ReceiverActor {
    
    private PublicKey publicKey;
    private PrivateKey privateKey;
    private PublicKey senderPubKey;
     SymetricCipherEngine cipher;
    
    public ReceiverActor() {
         KeyPair par = GeneratorKeyPair.generate("chaves");
        this.privateKey = par.getPrivate();
        this.publicKey = par.getPublic();
        cipher = new SymetricCipherEngine();
    }

    public void reveiveAuthMessage(PGPAuthMessage pgpMsg) {

        if (verificaAssinatura(pgpMsg.getAssinatura(), this.senderPubKey)
                && verificaHash(pgpMsg.getMsg(), pgpMsg.getMsgHash())) {
            System.out.println("Receiver: mensaagem recebida foi: " + pgpMsg.getMsg());

        } else {
            System.out.println("Receiver: erro ao ler a menssagem");
        }
    }
    
    public void receiveConfMessage(PGPConfMessage pgpMsg)
    {  
        byte[] secretkey = desencriptaChaveSecreta(pgpMsg.get_secretkey_cipher_with_PubKey());
         byte[] msg = desencriptaMsg(secretkey,pgpMsg.get_msg_cipher_with_secrectkey());
        try {
            String value = new String(msg, "UTF-8");
            System.out.println("Receiver: Menssagem recebida foi : " + value);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(ReceiverActor.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println("Erro ao escrever msg");
        }
    }

    private byte[] desencriptaChaveSecreta(byte[] chaveCript){
      
        byte[] result = null;
        try{
        result = cipher.decryptData(chaveCript, this.privateKey,SignatureEnum.RSA_ECB_PKCS1Padding);
        }catch(Exception e)
        {
              System.out.println("erro ao desencriptar com a chave privada");
        }
        return result;
    }
    
    private byte[] desencriptaMsg(byte[] chaveCript,byte[] msgCript){
          SecretKeySpec secretKeySpecDecrypted = new SecretKeySpec(chaveCript,"AES");
        byte[] result = null;
        try{
        result = this.cipher.decryptData(msgCript, secretKeySpecDecrypted,CipherAlgorithmEnum.AES);
        }        
        catch(Exception e)
        {
              System.out.println("erro ao desencriptar com a chave privada");
        }
        return result;
    
    }
    
    private boolean verificaHash(String msg, String msgHash) {
        if (msgHash.equals(generateMsgHash(msg))) {
            System.out.println("Receiver: hash verificado");
            return true;
        }

        System.out.println("Receiver: hash nao verificado");
        return false;
    }

    private String generateMsgHash(String msg) {
        SHAHashGenerator hashgen = new SHAHashGenerator();
        return hashgen.generateStringHash(msg);

    }

    private boolean verificaAssinatura(byte[] assinatura, PublicKey publicKey) {
        VerifySignatureActor actor = new VerifySignatureActor();
       
        if (actor.doVerifySignature(publicKey, assinatura)) {
            System.out.println("Receiver: Assinatura verificada");
            return true;
        }

        System.out.println("Receiver: Assinatura não verificada");
        return false;
    }
    
     public void receivePGPMessage(PGPMessage pGPMessage) {
         this.receiveConfMessage(pGPMessage.getConf());
         this.reveiveAuthMessage(pGPMessage.getAuth());
     }
    
    public PublicKey getPubKey()
    {
        return this.publicKey;
    }
    
     public void setSenderPubKey(PublicKey key)
    {
    this.senderPubKey = key;
    }

   
    
}
